#ifndef __SYLAR_TIMER_H__
#define __SYLAR_TIMER_H__

#include <memory>
#include <set>
#include <vector>
#include "thread.h"

namespace sylar{

class TimerManager;
/**
 * @brief 定时器类
 */
class Timer : public std::enable_shared_from_this<Timer>{
friend class TimerManager;
public:
	typedef std::shared_ptr<Timer> ptr;
	/**
	 * @brief 取消定时器, 不执行回调函数
	 */
	bool cancle();
	/**
	 * @brief 刷新重置定时器
	 */
	bool refresh();
	/**
	 * @brief 重置定时器的执行周期
	 */
	bool reset(uint64_t ms, bool from_now);
private:
	Timer(uint64_t ms, std::function<void()> cb, bool recurring, TimerManager* manager);
	Timer(uint64_t next);
private:
	bool m_recurring = false; 	// 是否是循环定时器
	uint64_t m_ms = 0;			// 执行周期
	uint64_t m_next = 0;		// 精确执行时间
	std::function<void()> m_cb;	// 定时器的回调函数
	TimerManager* m_manager = nullptr;	//定时器所属manager
private:
	struct Comparator{
		bool operator()(const Timer::ptr& lhs, const Timer::ptr& rhs);
	};
};


class TimerManager{
friend class Timer;
public:
	typedef RWMutex RWMutexType;
	
	TimerManager();
	virtual ~TimerManager();
	Timer::ptr addTimer(uint64_t ms, std::function<void()> cb, bool recurring = false);
	/**
	 * @brief 添加条件定时器 即weak_ptr的值可以获得时运行
	 */
	Timer::ptr addConditionTimer(uint64_t ms, std::function<void()> cb, std::weak_ptr<void> weak_cond, bool recurring = false);
	/**
	 * @brief 得到距离下一个需要运行的timer的时间
	 */
	uint64_t getNextTimer();
	/**
	 * @brief 返回所有的已经到达的定时器
	 */
	void listExpiredCb(std::vector<std::function<void()> >& cbs);
protected:
	/**
	 * @brief 存在一个timer插入到了队首 需要tickle唤醒 更新epollwait的超时时间
	 */
	virtual void onTimerInsertedAtFront() = 0;
	/**
	 *添加计时器 需要传入写锁
	 */
	void addTimer(Timer::ptr val, RWMutexType::WriteLock& lock);
	bool hasTimer();
private:
	/**
	 * @brief 排除系统时间回滚问题
	 */
	bool deleteClockRollover(uint64_t now_ms);
private:
	RWMutexType m_mutex;
	std::set<Timer::ptr, Timer::Comparator> m_timers;
	bool m_tickled = false;
	uint64_t m_previouseTime = 0;
};

} //namespace sylar

#endif